fn main() {
    let x = 5;
    let y = x; // 不变变量,保存在栈上, 赋值时自动(深)复制
               // 元组，当且仅当其包含的类型也都实现 Copy 的时候。比如，(i32, i32) 实现了 Copy，但 (i32, String) 就没有。
    println!("{x},{y}");

    let s1 = String::from("hello"); // s1 在栈上,内容在堆, s1只是保存的堆上内容的地址,和长度等信息

    let s2 = s1; // s1已经被释放了
    let s3 = s2.clone(); // 显式深度复制, 堆上内容复制一份,并将地址等信息赋给 s3

    // println!("{}", s1); // value borrowed here after move, 所有权转移后不能再使用
    println!("{s2},{s3}");

    // 函数参数传值与赋值的规则相同: 值类型copy 引用类型 move
    takes_ownership(s3);
    // println!("{s3}"); // value borrowed here after move
    makes_copy(y);
    println!("{y}");
}

fn takes_ownership(some_string: String) {
    // some_string 进入作用域
    println!("{}", some_string);
} // 这里，some_string 移出作用域并调用 `drop` 方法。
  // 占用的内存被释放

fn makes_copy(some_integer: i32) {
    // some_integer 进入作用域
    println!("{}", some_integer);
} // 这里，some_integer 移出作用域。没有特殊之处
